/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * ConstraintPanelVisual.java
 *
 * Created on Jul 20, 2010, 11:25:13 AM
 */

package org.netbeans.modules.javaee.beanvalidation;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.openide.loaders.TemplateWizard;
import org.openide.util.NbBundle;

/**
 *
 * @author alex
 */
public class ConstraintPanelVisual extends javax.swing.JPanel implements DocumentListener{

    private TemplateWizard wizard;
    private static final String VALIDATOR = "Validator";    //NOI18N
    private static final String METHOD = "METHOD";   //NOI18N
    private static final String FIELD = "FIELD";    //NOI18N
    private static final String ANNOTATION_TYPE = "ANNOTATION_TYPE";    //NOI18N
    private final List<String> targetElements = new ArrayList<String>();

    /** Creates new form ConstraintPanelVisual */
    public ConstraintPanelVisual(TemplateWizard wizard) {
        this.wizard = wizard;
        initComponents();

        setValidatorPropertiesVisible(false);
        validatorClassName.getDocument().addDocumentListener(this);
        validatorType.getDocument().addDocumentListener(this);
        targetElements.add(METHOD);
        targetElements.add(FIELD);
        targetElements.add(ANNOTATION_TYPE);
    }
    private final Set<ChangeListener> listeners = new HashSet<ChangeListener>(1);

    public final void addChangeListener(ChangeListener l) {
        synchronized (listeners) {
            listeners.add(l);
        }
    }
    public final void removeChangeListener(ChangeListener l) {
        synchronized (listeners) {
            listeners.remove(l);
        }
    }

    private void fireChangeEvent() {
        ChangeEvent e = new ChangeEvent(this);
        for (ChangeListener l : listeners) {
            l.stateChanged(e);
        }
    }
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        cbGenerateValidator = new javax.swing.JCheckBox();
        labelClassName = new javax.swing.JLabel();
        validatorClassName = new javax.swing.JTextField();
        labelType = new javax.swing.JLabel();
        validatorType = new javax.swing.JTextField();

        cbGenerateValidator.setText(org.openide.util.NbBundle.getMessage(ConstraintPanelVisual.class, "ConstraintPanelVisual.cbGenerateValidator.text")); // NOI18N
        cbGenerateValidator.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                cbGenerateValidatorItemStateChanged(evt);
            }
        });

        labelClassName.setText(org.openide.util.NbBundle.getMessage(ConstraintPanelVisual.class, "ConstraintPanelVisual.labelClassName.text")); // NOI18N

        validatorClassName.setColumns(20);

        labelType.setText(org.openide.util.NbBundle.getMessage(ConstraintPanelVisual.class, "ConstraintPanelVisual.labelType.text")); // NOI18N

        validatorType.setColumns(20);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(cbGenerateValidator)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(labelClassName)
                            .addComponent(labelType))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(validatorType, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE)
                            .addComponent(validatorClassName, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(0, 0, 0)
                .addComponent(cbGenerateValidator)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(labelClassName)
                    .addComponent(validatorClassName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(labelType)
                    .addComponent(validatorType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(224, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void cbGenerateValidatorItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbGenerateValidatorItemStateChanged
        // TODO add your handling code here:
        boolean visible = cbGenerateValidator.isSelected();
        setValidatorPropertiesVisible(visible);
        fireChangeEvent();
    }//GEN-LAST:event_cbGenerateValidatorItemStateChanged

    private void setValidatorPropertiesVisible(boolean visible) {
        labelClassName.setVisible(visible);
        labelType.setVisible(visible);
        validatorClassName.setVisible(visible);
        validatorType.setVisible(visible);
    }

    boolean validateTemplate(TemplateWizard wizard) {
        this.wizard = wizard;
        String message = null;
        wizard.putProperty(TemplateWizard.PROP_ERROR_MESSAGE, null);
        if (cbGenerateValidator.isSelected()) {
            if ("".equals(validatorClassName.getText().trim())) {
                wizard.putProperty(TemplateWizard.PROP_ERROR_MESSAGE, NbBundle.getMessage(ConstraintPanelVisual.class, "ERR_Empty_validator_class"));
                return false;
            }
            String type = validatorType.getText().trim();
            if ("".equals(type)) {
                wizard.putProperty(TemplateWizard.PROP_ERROR_MESSAGE, NbBundle.getMessage(ConstraintPanelVisual.class, "ERR_Empty_validator_type"));
                return false;
            }
            if (!isValidType(wizard, type)) {
                wizard.putProperty(TemplateWizard.PROP_ERROR_MESSAGE, NbBundle.getMessage(ConstraintPanelVisual.class, "ERR_wrong_type"));
                return false;
            }
        }
        return true;
    }

    private boolean isValidType(TemplateWizard wizard ,final String type) {
        //TODO XXX Need to validate type
        return true;
    }

    void updateValidatorClassName(String targetName) {
        String text = targetName + VALIDATOR;
        if (!text.equals(validatorClassName.getText().trim())) {
            validatorClassName.setText(targetName + VALIDATOR);
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox cbGenerateValidator;
    private javax.swing.JLabel labelClassName;
    private javax.swing.JLabel labelType;
    private javax.swing.JTextField validatorClassName;
    private javax.swing.JTextField validatorType;
    // End of variables declaration//GEN-END:variables

    @Override
    public void insertUpdate(DocumentEvent e) {
        fireChangeEvent();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        fireChangeEvent();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        fireChangeEvent();
    }

    void store(TemplateWizard settings) {
        settings.putProperty("targetElements", targetElements);
        if (cbGenerateValidator.isSelected()) {
            settings.putProperty("validator", validatorClassName.getText().trim());
            settings.putProperty("validatorType", validatorType.getText().trim());
        }
    }
}
